import React, { createContext } from 'react';
import LocaleProvider from '../locale-provider';

/* 样式前缀定义 START */
//须与default.scss中的样式前缀保持一直
export const defaultPrefixCls = 'au';
export const defaultIconPrefixCls = 'au-icon';
/* 样式前缀定义 END */

interface ConfigConsumerProps {
  locale: string;
  renderEmpty: Function;
  prefixCls: string;
  iconPrefixCls: string;
  size: string;
  getPrefixCls: (configPrefixCls?: string, suffixCls?: string, customizePrefixCls?: string) => string;
}

export const ConfigContext = createContext<ConfigConsumerProps>({
  prefixCls: defaultPrefixCls, //默认前缀
  iconPrefixCls: defaultIconPrefixCls, //默认图标样式前缀
  locale: 'zh-CN', //默认语言
  size: 'middle', //默认大小
  renderEmpty: () => 'empty',
  getPrefixCls: (configPrefixCls?: string, suffixCls?: string, customizePrefixCls?: string) => {
    // 获取样式前缀方法
    if (customizePrefixCls) return customizePrefixCls;
    configPrefixCls = configPrefixCls || defaultPrefixCls;
    return suffixCls ? `${configPrefixCls}-${suffixCls}` : configPrefixCls;
  },
});

ConfigContext.displayName = 'ConfigProvider';

/**
 * 上下文提供者结构
 */
type ConfigProviderProps = Partial<ConfigConsumerProps> & {
  children: React.ReactNode;
}

/**
 * 合并父子上下文结构
 */
interface ProviderChildrenProps extends ConfigProviderProps {
  parentContext: ConfigConsumerProps;
}

function ProviderChildren(props: ProviderChildrenProps) {
  const { children, parentContext, ...MergeContext } = props; // 只处理可能存在的最近的Provider context和children元素

  const config = React.useMemo(() => {
    return {
      ...parentContext,
      ...MergeContext
    };
  }, [MergeContext]);

  return <ConfigContext.Provider value={config}>
    <ConfigContext.Consumer>
      {
        context => {
          return <LocaleProvider locale={context.locale}>
            {children}
          </LocaleProvider>;
        }
      }
    </ConfigContext.Consumer>
  </ConfigContext.Provider>;
}

export const ConfigConsumer = ConfigContext.Consumer;

export function ConfigProvider(props: ConfigProviderProps) {
  return <ConfigConsumer>{
    context => <ProviderChildren {...props} parentContext={context} />
  }</ConfigConsumer>;
}

ConfigProvider.ConfigContext = ConfigContext;

// <ConfigProvider size='large'>
//   <App/>
// </ConfigProvider>
